package com.logos.musicframe.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.logos.musicframe.constant.RedisConstant;
import com.logos.musicframe.converter.PlaylistConverter;
import com.logos.musicframe.converter.SongsConverter;
import com.logos.musicframe.entity.Playlist;
import com.logos.musicframe.entity.PlaylistCollected;
import com.logos.musicframe.entity.Songs;
import com.logos.musicframe.entity.SongsLiked;
import com.logos.musicframe.enums.IsLikedEnum;
import com.logos.musicframe.mapper.*;
import com.logos.musicframe.req.PlaylistReq;
import com.logos.musicframe.resp.PlaylistResp;
import com.logos.musicframe.resp.SongsResp;
import com.logos.musicframe.resp.UsersResp;
import com.logos.musicframe.service.FileService;
import com.logos.musicframe.service.PlaylistService;
import com.logos.musicframe.service.UsersService;
import com.logos.musicframe.utils.RedisUtil;
import com.logos.musicframe.utils.UserInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 歌单表(Playlist)表服务实现类
 *
 * @author logos
 * @since 2025-06-14 21:28:44
 */
@Service("playlistService")
@Slf4j
public class PlaylistServiceImpl implements PlaylistService {

    @Autowired
    private PlaylistMapper playlistMapper;

    @Autowired
    private SongsMapper songsMapper;

    @Autowired
    private SongsPlaylistMapper songsPlaylistMapper;

    @Autowired
    private PlaylistCollectedMapper playlistCollectedMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private UserInfoUtil userInfoUtil;

    @Autowired
    private FileService fileService;

    @Autowired
    private UsersService usersService;

    @Autowired
    private SongsLikedMapper songsLikedMapper;

    /**
     * 通过ID查询单条数据
     *
     * @return 实例对象
     */
    @Override
    public PlaylistResp queryById(PlaylistReq playlistReq) {
        // 查询缓存中是否存在
        if (redisUtil.exist(RedisConstant.PLAYLIST_ID + playlistReq.getId())) {
            String playlistRespStr = redisUtil.get(RedisConstant.PLAYLIST_ID + playlistReq.getId());
            PlaylistResp playlistResp = JSONObject.parseObject(playlistRespStr, PlaylistResp.class);
            log.info("playlistService.queryById.Cache.Hit:{}", playlistResp);
            return playlistResp;
        }
        Playlist playlist = PlaylistConverter.INSTANCE.convertReqToEntity(playlistReq);
        List<Playlist> playlistList = playlistMapper.queryByCondition(playlist);
        if (playlistList == null || playlistList.isEmpty()) {
            return null;
        }
        playlist = playlistList.get(0);
        // 同时把该歌单的歌曲查出来
        PlaylistResp playlistResp = PlaylistConverter.INSTANCE.convertEntityToResp(playlist);
        List<Integer> songIds = songsPlaylistMapper.queryByPlaylistId(playlist.getId());
        if (songIds == null || songIds.isEmpty()) {
            playlistResp.setSongsRespList(new ArrayList<>());
        } else {
            List<SongsResp> songsRespList = songsMapper.queryByIds(songIds).stream().map(SongsConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
            playlistResp.setSongsRespList(songsRespList);
        }
        // 根据创建人id查询创建人姓名
        playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlist.getCreatedBy()));
        // 存入缓存
        redisUtil.setNx(RedisConstant.PLAYLIST_ID + playlist.getId(), JSONObject.toJSONString(playlistResp), RedisConstant.EXPIRE_TIME_THREE_MINUTES);
        return playlistResp;
    }

    /**
     * 新增数据
     *
     * @param playlist 实例对象
     * @return 实例对象
     */
    @Override
    public Playlist insert(Playlist playlist) {
        this.playlistMapper.insert(playlist);
        return playlist;
    }

    /**
     * 修改数据
     *
     * @param playlist 实例对象
     * @return 实例对象
     */
    @Override
    public Playlist update(Playlist playlist) {
        return null;
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.playlistMapper.deleteById(id) > 0;
    }

    @Override
    public List<PlaylistResp> queryCreated(Integer userId) {
        // 先判断Redis中是否有数据
        if (redisUtil.exist(RedisConstant.PLAYLIST_CREATED_USER + userId)) {
            List<PlaylistResp> playlistRespList = JSONObject.parseArray(redisUtil.get(RedisConstant.PLAYLIST_CREATED_USER + userId), PlaylistResp.class);
            log.info("playlistService.queryCreated.Cache.Hit:{}", playlistRespList);
            return playlistRespList;
        }
        Playlist playlist = new Playlist().setCreatedBy(userId);
        List<Playlist> playlistList = playlistMapper.queryByCondition(playlist);
        List<PlaylistResp> playlistRespList = playlistList.stream().map(PlaylistConverter.INSTANCE::convertEntityToResp).toList();
        // 根据歌单的id查询歌单包含歌曲id
        // 传统方式
        /*for (PlaylistResp playlistResp : playlistRespList) {
            Long playlistId = playlistResp.getId();
            List<Integer> songIdList = songsPlaylistMapper.queryByPlaylistId(playlistId);
            // 根据songId查询对应歌曲
            if (songIdList == null || songIdList.isEmpty()) {
                playlistResp.setSongsRespList(new ArrayList<>());
                continue;
            }
            List<Songs> songsList = songsMapper.queryByIds(songIdList);
            List<SongsResp> songsRespList = songsList.stream().map(SongsConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
            // 查询歌曲是否被喜欢
            for (SongsResp songsResp : songsRespList) {
                String key = RedisConstant.SONG_LIKED_USER_LIST + userId + RedisConstant.KEY_SEPARATOR + songsResp.getId();
                if (redisUtil.exist(key)) {
                    songsResp.setIsLiked(IsLikedEnum.LIKED.isDesc());
                } else {
                    songsResp.setIsLiked(IsLikedEnum.UN_LIKED.isDesc());
                }
            }
            playlistResp.setSongsRespList(songsRespList);
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlist.getCreatedBy()));
        }*/
        // CompletableFuture多线程优化
        List<PlaylistResp> playlistRespResult = playlistRespList.stream().map(playlistResp -> CompletableFuture.supplyAsync(() -> {
            Long playlistId = playlistResp.getId();
            List<Integer> songIdList = songsPlaylistMapper.queryByPlaylistId(playlistId);
            // 根据songId查询对应歌曲
            if (songIdList == null || songIdList.isEmpty()) {
                playlistResp.setSongsRespList(new ArrayList<>());
            } else {
                List<Songs> songsList = songsMapper.queryByIds(songIdList);
                List<SongsResp> songsRespList = songsList.stream().map(SongsConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
                // 查询歌曲是否被喜欢
                for (SongsResp songsResp : songsRespList) {
                    // 去数据库里查
                    List<SongsLiked> songsLikedList = songsLikedMapper.queryByCondtion(new SongsLiked().setUserId(userId).setSongId(songsResp.getId()));
                    if (songsLikedList != null && songsLikedList.size() > 0) {
                        songsResp.setIsLiked(IsLikedEnum.LIKED.isDesc());
                    } else {
                        songsResp.setIsLiked(IsLikedEnum.UN_LIKED.isDesc());
                    }
                }
                playlistResp.setSongsRespList(songsRespList);
            }
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlist.getCreatedBy()));
            return playlistResp;
        })).toList().stream().map(CompletableFuture::join).collect(Collectors.toList());
        // 存入Redis中
        redisUtil.setNx(RedisConstant.PLAYLIST_CREATED_USER + userId, JSONObject.toJSONString(playlistRespResult), RedisConstant.EXPIRE_TIME_THREE_MINUTES);
        return playlistRespResult;
    }

    private String queryUserNameByCreatedUserId(Integer userId) {
        // 根据创建人id查询创建人姓名
        UsersResp usersResp = usersService.queryById(userId);
        return usersResp.getUsername();
    }

    @Override
    public PlaylistResp add(PlaylistReq playlistReq) {
        Playlist playlist = PlaylistConverter.INSTANCE.convertReqToEntity(playlistReq);
        // 上传封面
        File coverFile = playlistReq.getCoverFile();
        if (coverFile != null && coverFile.exists()) {
            String fileUrl = fileService.uploadFile(coverFile);
            playlist.setCoverUrl(fileUrl);
        }
        int count = playlistMapper.insert(playlist);
        if (count <= 0) {
            return null;
        }
        playlist = playlistMapper.queryById(playlist.getId());
        // 删除缓存
        redisUtil.del(RedisConstant.PLAYLIST_CREATED_USER + playlist.getCreatedBy());
        return PlaylistConverter.INSTANCE.convertEntityToResp(playlist);
    }

    /**
     * 根据歌单id列表查询歌单
     *
     * @param playListIdList
     * @return
     */
    @Override
    public List<PlaylistResp> queryByIds(List<Long> playListIdList) {
        // 普通方法
        /*List<PlaylistResp> playlistRespList = new CopyOnWriteArrayList<>();
        for (Long playlistId : playListIdList) {
            // 查询缓存是否命中
            if (redisUtil.exist(RedisConstant.PLAYLIST_ID + playlistId)) {
                PlaylistResp playlistResp = JSONObject.parseObject(redisUtil.get(RedisConstant.PLAYLIST_ID + playlistId), PlaylistResp.class);
                log.info("playlistService.queryByIds.Cache.Hit:{}", playlistResp);
                playlistRespList.add(playlistResp);
                continue;
            }
            Playlist playlist = playlistMapper.queryById(playlistId);
            PlaylistResp playlistResp = PlaylistConverter.INSTANCE.convertEntityToResp(playlist);
            // 根据歌单id查询歌曲id
            List<Integer> songIdList = songsPlaylistMapper.queryByPlaylistId(playlistId);
            if (songIdList != null && !songIdList.isEmpty()) {
                // 根据歌曲id查询歌曲
                List<SongsResp> songsRespList = songsMapper.queryByIds(songIdList).stream().map(SongsConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
                playlistResp.setSongsRespList(songsRespList);
                playlistRespList.add(playlistResp);
            } else {
                playlistRespList.add(null);
            }
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlist.getCreatedBy()));
            // 存入缓存
            redisUtil.setNx(RedisConstant.PLAYLIST_ID + playlistId, JSONObject.toJSONString(playlistResp), RedisConstant.EXPIRE_TIME_THREE_MINUTES);
        }*/
        // CompletableFuture多线程优化
        List<PlaylistResp> playlistRespList = playListIdList.stream().map(playlistId -> CompletableFuture.supplyAsync(() -> {
            // 查询缓存是否命中
            if (redisUtil.exist(RedisConstant.PLAYLIST_ID + playlistId)) {
                PlaylistResp playlistResp = JSONObject.parseObject(redisUtil.get(RedisConstant.PLAYLIST_ID + playlistId), PlaylistResp.class);
                log.info("playlistService.queryByIds.Cache.Hit:{}", playlistResp);
                return playlistResp;
            }
            Playlist playlist = playlistMapper.queryById(playlistId);
            PlaylistResp playlistResp = PlaylistConverter.INSTANCE.convertEntityToResp(playlist);
            // 根据歌单id查询歌曲id
            List<Integer> songIdList = songsPlaylistMapper.queryByPlaylistId(playlistId);
            if (songIdList != null && !songIdList.isEmpty()) {
                // 根据歌曲id查询歌曲
                List<SongsResp> songsRespList = songsMapper.queryByIds(songIdList).stream().map(SongsConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
                playlistResp.setSongsRespList(songsRespList);
            } else {
                playlistResp.setSongsRespList(new ArrayList<>());
            }
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlist.getCreatedBy()));
            // 存入缓存
            redisUtil.setNx(RedisConstant.PLAYLIST_ID + playlistId, JSONObject.toJSONString(playlistResp), RedisConstant.EXPIRE_TIME_THREE_MINUTES);
            return playlistResp;
        })).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList());
        return playlistRespList;
    }

    @Override
    public List<PlaylistResp> queryAll() {
        Integer userId = userInfoUtil.getUserId();
        // 查询缓存中是否存在
        if (redisUtil.exist(RedisConstant.PLAYLIST_ALL + userId)) {
            String resultStr = redisUtil.get(RedisConstant.PLAYLIST_ALL + userId);
            List<PlaylistResp> playlistRespList = JSONObject.parseArray(resultStr, PlaylistResp.class);
            log.info("playlistService.queryAll.Cache.Hit:{}", playlistRespList);
            return playlistRespList;
        }
        // 查询出所有歌单
        List<Playlist> playlistList = playlistMapper.queryAll();
        List<PlaylistResp> playlistRespList = playlistList.stream().map(PlaylistConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
        // 取前十条
        playlistRespList = playlistRespList.stream().limit(10).collect(Collectors.toList());
        // 普通方式
        /*        for (PlaylistResp playlistResp : playlistRespList) {
            // 获取歌单内歌曲
            List<Integer> songIdList = songsPlaylistMapper.queryByPlaylistId(playlistResp.getId());
            List<SongsResp> songsRespList = new ArrayList<>();
            if (songIdList != null && songIdList.size() > 0) {
                songsRespList = songsMapper.queryByIds(songIdList).stream().map(SongsConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
            }
            playlistResp.setSongsRespList(songsRespList);
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlistResp.getCreatedBy()));
            // 查询该歌单是否被该用户收藏
            PlaylistCollected playlistCollected = playlistCollectedMapper.queryByCondition(new PlaylistCollected().setUserId(userInfoUtil.getUserId()).setPlaylistId(Math.toIntExact(playlistResp.getId())));
            playlistResp.setIsCollected(playlistCollected != null);
        }*/
        // CompletableFuture多线程优化
        List<PlaylistResp> playlistRespListResult = playlistRespList.stream().map(playlistResp -> CompletableFuture.supplyAsync(() -> {
            // 获取歌单内歌曲
            List<Integer> songIdList = songsPlaylistMapper.queryByPlaylistId(playlistResp.getId());
            List<SongsResp> songsRespList = new ArrayList<>();
            if (songIdList != null && !songIdList.isEmpty()) {
                songsRespList = songsMapper.queryByIds(songIdList).stream().map(SongsConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
            }
            playlistResp.setSongsRespList(songsRespList);
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlistResp.getCreatedBy()));
            // 查询该歌单是否被该用户收藏
            PlaylistCollected playlistCollected = playlistCollectedMapper.queryByCondition(new PlaylistCollected().setUserId(userInfoUtil.getUserId()).setPlaylistId(Math.toIntExact(playlistResp.getId())));
            playlistResp.setIsCollected(playlistCollected != null);
            return playlistResp;
        })).toList().stream().map(CompletableFuture::join).collect(Collectors.toList());
        // 设置缓存
        redisUtil.setNx(RedisConstant.PLAYLIST_ALL + userId, JSONObject.toJSONString(playlistRespListResult), RedisConstant.EXPIRE_TIME_THREE_MINUTES);
        return playlistRespList;
    }

    /**
     * 主页推荐歌单
     *
     * @return
     */
    @Override
    public List<PlaylistResp> getRecommendPlaylist() {
        Integer userId = userInfoUtil.getUserId();
        // 查看缓存中是否存在
        if (redisUtil.exist(RedisConstant.PLAYLIST_RECOMMEND + userId)) {
            List<PlaylistResp> playlistRespList = JSONObject.parseArray(redisUtil.get(RedisConstant.PLAYLIST_RECOMMEND + userId), PlaylistResp.class);
            log.info("playlistService.getRecommendPlaylist.Cache.Hit:{}", playlistRespList);
            return playlistRespList;
        }
        List<Playlist> playlists = playlistMapper.queryAll();
        // 打乱
        Collections.shuffle(playlists);
        // 取前五个歌单
        playlists = playlists.subList(0, 5);
        List<PlaylistResp> playlistRespList = playlists.stream().map(PlaylistConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
        // 根据歌单查询歌曲 传统方式
/*        playlistRespList.forEach(playlistResp -> {
            // 获取该歌单的歌曲id
            List<Integer> songIdList = songsPlaylistMapper.queryByPlaylistId(playlistResp.getId());
            List<SongsResp> songsRespList = new ArrayList<>();
            if (songIdList != null && !songIdList.isEmpty()) {
                // 根据歌曲id查询歌曲
                songsRespList = songsMapper.queryByIds(songIdList).stream().map(songs -> SongsConverter.INSTANCE.convertEntityToResp(songs)).collect(Collectors.toList());
            }
            playlistResp.setSongsRespList(songsRespList);
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlistResp.getCreatedBy()));
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlistResp.getCreatedBy()));
            // 查询该歌单是否被该用户收藏
            PlaylistCollected playlistCollected = playlistCollectedMapper.queryByCondition(new PlaylistCollected().setUserId(userId).setPlaylistId(Math.toIntExact(playlistResp.getId())));
            playlistResp.setIsCollected(playlistCollected != null);
        });*/
        // CompletableFuture多线程优化
        List<PlaylistResp> playlistRespListResult = playlistRespList.stream().map(playlistResp -> CompletableFuture.supplyAsync(() -> {
            // 获取该歌单的歌曲id
            List<Integer> songIdList = songsPlaylistMapper.queryByPlaylistId(playlistResp.getId());
            List<SongsResp> songsRespList = new ArrayList<>();
            if (songIdList != null && !songIdList.isEmpty()) {
                // 根据歌曲id查询歌曲
                songsRespList = songsMapper.queryByIds(songIdList).stream().map(SongsConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
            }
            playlistResp.setSongsRespList(songsRespList);
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlistResp.getCreatedBy()));
            // 根据创建人id查询创建人姓名
            playlistResp.setCreatedByName(queryUserNameByCreatedUserId(playlistResp.getCreatedBy()));
            // 查询该歌单是否被该用户收藏
            PlaylistCollected playlistCollected = playlistCollectedMapper.queryByCondition(new PlaylistCollected().setUserId(userId).setPlaylistId(Math.toIntExact(playlistResp.getId())));
            playlistResp.setIsCollected(playlistCollected != null);
            return playlistResp;
        })).toList().stream().map(CompletableFuture::join).collect(Collectors.toList());
        // 存入缓存
        redisUtil.setNx(RedisConstant.PLAYLIST_RECOMMEND + userId, JSONObject.toJSONString(playlistRespListResult), RedisConstant.EXPIRE_TIME_THREE_MINUTES);
        return playlistRespList;
    }
}
